Ubuntuでcfn-initを利用する時の注意点
こんにちは、藤本です。
先日初めてUbuntuのEC2インスタンスに対して、CloudFormationヘルパースクリプトを利用した時にいくつかハマってしまったのでご紹介します。
前提知識
CloudFormationはEC2インスタンス構築時にOS内をカスタマイズするツールとして、CloudFormationヘルパースクリプトを用意しています。詳細はAWSのドキュメントや弊社の過去エントリをご参照ください。
- AWSドキュメントページ
- Developers.IO
環境
AMI : Ubuntu Server 14.04 LTS (HVM), SSD Volume Type - ami-a21529cc
easy_installよりもpipでインストールした方がいい
CloudFormationヘルパースクリプトはrpm、tar.gz、zip、msiで提供されています。Amazon Linuxであればデフォルトでインストールされていますし、CentOS、RHELであればrpm
で簡単にインストールすることができます。
Ubuntuの場合はAWSドキュメントページを参照すると以下の2点が記載されています。
- https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gzから"Python easy-install tools"を利用してインストールする
cfn-hup
自動起動スクリプトは/etc/init.d/
へ配置されないため、インストールファイルからシンボリックリンクを張る
ただインストール方法がeasy_install
か、pip
かによって、cfn-hup
のインストールパスが異なります。easy_install
の場合、ヘルパースクリプトのバージョン情報が記載されるため、CloudFormationの使い回しを考慮する場合、バージョンによる影響を受けないpip
を利用することを推奨します。
easy_install
の場合- /usr/local/lib/python2.7/dist-packages/aws_cfn_bootstrap-1.4-py2.7.egg/init/ubuntu/cfn-hup
pip
の場合- /usr/local/init/ubuntu/cfn-hup
例
"Resources": { "Instance": { "Type": "AWS::EC2::Instance", "Properties": { : "UserData": {"Fn::Base64": {"Fn::Join": ["", [ "#!/bin/bash -xe\n", "apt-get update\n", "apt-get -y install python-pip\n", "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n", "cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup\n", "chmod u+x /etc/init.d/cfn-hup\n", "/usr/local/bin/cfn-init -v ", " --stack ", {"Ref": "AWS::StackName"}, " --resource Instance ", " --configsets setup ", " --region ", {"Ref": "AWS::Region"}, "\n", "/usr/local/bin/cfn-signal -e $? ", " --stack ", {"Ref": "AWS::StackName"}, " --resource Instance ", " --region ", {"Ref": "AWS::Region"}, "\n" ] ]} } }, "Metadata": { "AWS::CloudFormation::Init": { : "initialize": { "files": { "/etc/cfn/cfn-hup.conf": { "content": {"Fn::Join": ["", [ "[main]\n", "stack=", {"Ref": "AWS::StackId"}, "\n", "region=", {"Ref": "AWS::Region"}, "\n" ]]}, "mode" : "000400", "owner": "root", "group": "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf": { "content": {"Fn::Join": ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.Instance.Metadata.AWS::CloudFormation::Init\n", "action=/usr/local/bin/cfn-init -v ", " --stack ", {"Ref": "AWS::StackName"}, " --resource Instance ", " --configsets setup ", " --region ", {"Ref": "AWS::Region"}, "\n" ]]}, "mode" : "000400", "owner": "root", "group": "root" } }, "services": { "sysvinit": { "cfn-hup": {"enabled": "true", "ensureRunning": "true", "files": ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } :
自動起動設定
cfn-init
ではServicesによりサービスの自動起動設定を管理することができます。
Ubuntu 14.04は自動起動の管理にinitctl
や/etc/rc*.d
(update-rc.d
、insserv
)などいくつかの仕組みがあります。cfn-init
のservicesキーではupdate-uc.d
を利用します。そのため、initctl
でサービスを管理したい場合、servicesキーでは実装することができません。filesキーやcommandsキーで実装する必要があります。
squid
はinitctl
で管理されるため、以下のように記載をするとエラーとなる
: "Resources": { "Instance": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { : "setup": { "packages": { "apt" : { "squid": [] } }, "services": { "sysvinit": { "squid" : { "enabled": "true", "ensureRunning": "true" } } } } :
対話処理を求められる場合の回避方法
Ubuntuでパッケージのインストールや、パッケージのセットアップツールなどを実行する時に背景が紫色になって対話型の入力を求められるケースが多々あります。cfn-init
のように人の手を介さず自動的に処理したい場合、対話処理を回避する必要があります。
そのような場合、環境変数DEBIAN_FRONTEND
にnoninteractive
をセットしてください。
: "Resources": { "Instance": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { : "command": { "command-noninteractive": { "command": "DEBIAN_FRONTEND=noninteractive apt-get -y install xxxxxxxx" } } } } }, :
まとめ
いかがでしたでしょうか?
Amazon Linuxと同じように使えると思っていたら何回もエラーとなって大変でした。。
同じようなことにハマった人の参考になれば幸いです。